/*
 * Copyright (c) 2016 Breezee.org. All Rights Reserved.
 */

package com.oj.common.domain;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.oj.common.IDumpObject;
import com.oj.common.constants.ConstantEnum;
import com.oj.common.constants.OperTypeEnum;
import com.oj.common.util.BreezeeUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 领域对象的基本信息
 * 将被系统内的所有领域对象所继承
 * Created by Bing on 2018/3/5.
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BaseInfo implements Serializable,
        Cloneable,
        Comparable<BaseInfo>,
        IDumpObject {

    /**
     * 数据主键
     */
    @JsonProperty("id")
    protected String id;

    /**
     * 业务主键
     */
    @JsonProperty("code")
    protected String code;

    /**
     * 名称
     */
    @JsonProperty("name")
    protected String name;

    /**
     * 状态
     */
    protected Integer status = 0;

    /**
     * 创建人
     */
    protected String creator;

    /**
     * 创建时间
     */
    protected Date createTime;

    /**
     * 更新人
     */
    protected String updator;

    /**
     * 更新时间
     */
    protected Date updateTime;


    /**
     * 操作类型：表示对此对象的操作行为
     */
    protected OperTypeEnum operType = OperTypeEnum.READ;

    /**
     * 数据状态，标识是新增，还是修改，还是删除
     * 在baseEntity里面设置的
     */
    protected Integer dataStatus = 0;

    /**
     * 扩展属性信息
     */
    @JsonProperty("properties")
    protected Map<String, Object> properties = new HashMap<>();

    /**
     * 状态的名称翻译，主要供页面的序列化使用
     *
     * @return
     */
    public String getStatusName() {
        return status + "";
    }

    public <T extends BaseInfo> T buildProperties(String key, Object value) {
        this.getProperties().put(key, value);
        return (T) this;
    }

    /**
     * 复制对象
     * 我们不用BeanUtil的方式实现，而是自己来实现
     * 一方面减少包的依赖，另外也是提高效率
     */
    @Override
    public BaseInfo clone() throws CloneNotSupportedException {
        return (BaseInfo) super.clone();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (this.id != null) {
            sb.append(this.getId());
        }
        if (this.code != null) {
            if (sb.length() > 0) {
                sb.append(",");
            }
            sb.append(this.getCode());
        }
        return sb.toString();
    }

    @Override
    public int hashCode() {
        if (this.getId() == null) {
            return super.hashCode();
        }
        return this.getId().hashCode() * 37 +
                (this.getCode() == null ? 0 : this.getCode().hashCode() * 37);
    }

    @Override
    public void dump() {
        System.out.println(this.id + "--" + this.code + "--" + this.name + "--" + this.status);
    }

    @Override
    public int compareTo(BaseInfo o) {
        return 0;
    }

    @Override
    public Object diff(Object o) throws RuntimeException {
        return BreezeeUtils.objectDiff(this, o, "lastTimes,updateTime,language,createTime");
    }

    public void addProperties(String key, Object val) {
        this.properties.put(key, val);
    }

    public Object pro(String key) {
        return this.properties.get(key);
    }
}
